#coding=utf-8
'''
Created on 2011-3-28

@author: Chine
'''
import urllib2

from django.contrib.syndication.views import add_domain
from django.contrib.sites.models import Site

from ChineKingBlog.weibopy.auth import OAuthHandler, WeibopError
from ChineKingBlog.weibopy import oauth
from ChineKingBlog.weibopy.api import API
from ChineKingBlog.weibopy.binder import bind_api
from shortener import get_short_url
from utils import strip_html

consumer_key = '2233047537'
consumer_secret = 'f1ccece91ac2a709e854f8b43c79838c'

token = "753e1835ddb80da35512e8d7840e3577"
tokenSecret = "d77b0cdfd52cdfc28d46cfaf8dcd9160"

class callable(object):
    def __call__(self):
        raise NotImplementedError
    
class WebOAuthHandler(OAuthHandler):
    def get_authorization_url_with_callback(self, callback, signin_with_weibo=False):
        try:
            self.request_token = self._get_request_token()
            
            if signin_with_weibo:
                url = self._get_request_token('authenticate')
            else:
                url = self._get_oauth_url('authorize')
            
            request = oauth.OAuthRequest.from_token_and_callback(
                token=self.request_token, callback=callback, http_url=url
            )
            return request.to_url()
        except Exception, e:
            raise WeibopError(e)
        
def _oauth():
    return WebOAuthHandler(consumer_key, consumer_secret)

class weibo(object):
    def __init__(self):
        self.consumer_key = consumer_key
        self.consumer_secret = consumer_secret
    
    def getAtt(self, key):
        try:
            return self.obj.__getattribute__(key)
        except Exception, e:
            print e
            return ''
        
    def getAttValue(self, obj, key):
        try:
            return obj.__getattribute__(key)
        except Exception, e:
            print e
            return ''
        
    def auth(self):
        self.auth = OAuthHandler(self.consumer_key, self.consumer_secret)
        auth_url = self.auth.get_authorization_url()
        print 'Please authorize: ' + auth_url
        verifier = raw_input('PIN: ').strip()
        self.auth.get_access_token(verifier)
        self.api = API(self.auth)
     
    def setToken(self, token, tokenSecret):
        self.auth = OAuthHandler(self.consumer_key, self.consumer_secret)
        self.auth.setToken(token, tokenSecret)
        self.api = API(self.auth)
    
    def update(self, message):
        message = message.encode("utf-8")
        status = self.api.update_status(status=message)
        self.obj = status
        id = self.getAtt("id")        
        return id
        
    def destroy_status(self, id):
        status = self.api.destroy_status(id)
        self.obj = status
        id = self.getAtt("id")        
        return id
    
    def comment(self, id, message):
        comment = self.api.comment(id=id, comment=message)
        self.obj = comment
        mid = self.getAtt("id")
        return mid
    
    def comment_destroy (self, mid):
        comment = self.api.comment_destroy(mid)
        self.obj = comment
        mid = self.getAtt("id")
        text = self.getAtt("text")
        return mid
    
    def repost(self, id, message):
        post = self.api.repost(id=id, status=message)
        self.obj = post
        mid = self.getAtt("id")
        return mid
    
    def get_username(self):
        if getattr(self, '_username', None) is None:
            self._username = self.auth.get_username()
        return self._username
    
    def get_status(self):
        status = self.api.verify_credentials()
        self.obj = status
        # id = status['id']
        # print status.__dict__
        # print status.profile_image_url
        return status.id, self.get_username(), status.url, status.profile_image_url
    
    '''
    def get_user_timeline(self):
        user_timeline = self.api.user_timeline()
        print dir(user_timeline)
        for status in user_timeline:
            print status.id, status.text
    '''

class weibo_myself(weibo):
    def __init__(self):
        weibo.__init__(self);
        self.setToken(token, tokenSecret)
    
    def send_weibo_by_myself(self, message):
        return self.update(message)

class article_send2_weibo(callable):
    def __init__(self, article):
        self._article = article
        self._len = 140
        
    def _get_url(self):
        current_site = Site.objects.get_current()
        return add_domain(current_site.domain, self._article.get_absolute_url())
    
    def _get_short_url(self):
        if getattr(self, '_short_url', None) is None:
            self._short_url = get_short_url(self._get_url())
        return self._short_url
    
    def _get_short_pic_url(self):
        return "%s.qr" % self._get_short_url()
    
    def _abs_len(self):
        return self._len - len(u"发表了文章《》 - ... ") - len(self._article.title) - len(self._get_short_url())
    
    def _get_content(self):
        if getattr(self, '_content', None) is None:
            self._content = strip_html(self._article.content)[:self._abs_len()]
        return self._content
    
    def _get_result(self):
        return u"发表了文章《%s》 - %s... %s" % (self._article.title, self._get_content(), self._get_short_url(), )
        
    def __call__(self):
        # self_weibo = weibo_myself()
        # return self_weibo.send_weibo_by_myself(self._get_result())
        self_weibo = PicWeiboMyself()
        return self_weibo.upload_by_myself(self._get_result(), self._get_short_pic_url())
    
class comment_2_article(callable):
    def __init__(self, comment):
        self._comment = comment
        
    def __call__(self, token, tokenSecret):
        weibo_client = weibo()
        weibo_client.setToken(token, tokenSecret)
        return weibo_client.comment(self._comment.article.weibo_id, self._comment.content)
    
class message_2_weibo(callable):
    def __init__(self, msg):
        self._msg = msg
        self._len = 140
        
    def _get_url(self):
        current_site = Site.objects.get_current()
        return add_domain(current_site.domain, '/contact/')
    
    def _get_short_url(self):
        if getattr(self, '_short_url', None) is None:
            self._short_url = get_short_url(self._get_url())
        return self._short_url
    
    def _abs_len(self):
        return self._len - len(u"对@秦续业 说：  ") - len(self._get_short_url())
    
    def _get_content(self):
        if getattr(self, '_content', None) is None:
            self._content = self._msg[:self._abs_len()]
        return self._content
    
    def _get_result(self):
        return u"对@秦续业 说：%s %s" % (self._get_content(), self._get_short_url(), )
        
    def __call__(self, token, tokenSecret):
        w = weibo()
        w.setToken(token, tokenSecret)
        return w.update(self._get_result())
    
class PICAPI(API):
    """ Internal use only """
    @staticmethod
    def _pack_url_image(url, max_size, source=None, status=None, lat=None, long=None, contentname="image"):
        """Pack image from file into multipart-formdata post body"""

        # build the mulitpart-formdata body
        fp = urllib2.urlopen(url)
        BOUNDARY = 'Tw3ePy'
        body = []
        if status is not None:            
            body.append('--' + BOUNDARY)
            body.append('Content-Disposition: form-data; name="status"')
            body.append('Content-Type: text/plain; charset=US-ASCII')
            body.append('Content-Transfer-Encoding: 8bit')
            body.append('')
            body.append(status)
        if source is not None:            
            body.append('--' + BOUNDARY)
            body.append('Content-Disposition: form-data; name="source"')
            body.append('Content-Type: text/plain; charset=US-ASCII')
            body.append('Content-Transfer-Encoding: 8bit')
            body.append('')
            body.append(source)
        if lat is not None:            
            body.append('--' + BOUNDARY)
            body.append('Content-Disposition: form-data; name="lat"')
            body.append('Content-Type: text/plain; charset=US-ASCII')
            body.append('Content-Transfer-Encoding: 8bit')
            body.append('')
            body.append(lat)
        if long is not None:            
            body.append('--' + BOUNDARY)
            body.append('Content-Disposition: form-data; name="long"')
            body.append('Content-Type: text/plain; charset=US-ASCII')
            body.append('Content-Transfer-Encoding: 8bit')
            body.append('')
            body.append(long)
        body.append('--' + BOUNDARY)
        body.append('Content-Disposition: form-data; name="'+ contentname +'"; filename="%s"' % url)
        body.append('Content-Type: ')
        body.append('Content-Transfer-Encoding: binary')
        body.append('')
        body.append(fp.read())
        body.append('--' + BOUNDARY + '--')
        body.append('')
        fp.close()        
        body.append('--' + BOUNDARY + '--')
        body.append('')
        body = '\r\n'.join(body)
        # build headers
        headers = {
            'Content-Type': 'multipart/form-data; boundary=Tw3ePy',
            'Content-Length': len(body)
        }

        return headers, body
    
    """ statuses/upload """
    def upload2(self, url, status, lat=None, long=None, source=None):
        if source is None:
            source=self.source
        headers, post_data = PICAPI._pack_url_image(url, 1024, source=source, status=status, lat=lat, long=long, contentname="pic")
        args = [status]
        allowed_param = ['status']
        
        if lat is not None:
            args.append(lat)
            allowed_param.append('lat')
        
        if long is not None:
            args.append(long)
            allowed_param.append('long')
        
        if source is not None:
            args.append(source)
            allowed_param.append('source')
        return bind_api(
            path = '/statuses/upload.json',            
            method = 'POST',
            payload_type = 'status',
            require_auth = True,
            allowed_param = allowed_param            
        )(self, *args, post_data=post_data, headers=headers)
        
class PicWeibo(weibo):
    def upload2(self, message, url):
        api = PICAPI(self.auth)
        
        message = message.encode("utf-8")
        url = url.encode("utf-8")
        status = api.upload2(url, message)
        self.obj = status
        id = self.getAtt("id")        
        return id
    
class PicWeiboMyself(weibo_myself, PicWeibo):
    def upload_by_myself(self, message, url):
        return self.upload2(message, url)
